#include <iostream>
#include <string.h>
#include <string>
#include <cstdio>
#include "Student.h"

//    编这个程序领悟到的最重要的一点：
//    千万不要在这个数据还没定义的情况下，
//    和其他数据作比较！！！！！

using namespace std;

System::System()    //初始化：数据归零
{
    for(int i = 0; i < 30; i ++)
    {
        pStudent[i] = 0;
    }
}

void System::PushPupil()
{
    int n;
    for(n = 0; pStudent[n] != 0&&n < 30; n ++);
//    这里有个小问题：学生数据总数可能超过了30，
//    此时应该停止并提示用户（待优化）；
    Loop:
    pStudent[n] = new Pupil;
    pStudent[n]->Add();
//    查看添加的数据里ID是否重复了
    for(int i = 0; i < 30; i ++)
    {
//        这里必须先看i和n是否相等（不然我自己比我自己有什么意义？）
        if(i != n&&pStudent[i] != 0&&pStudent[i]->id == pStudent[n]->id)
        {
            cout<<"It seems that the ID had been recorded, please try again."<<endl<<endl;
            delete pStudent[n];
            goto Loop;
//    还是有点小问题：即使ID重复被找出后仁然会显示“数据已记录！”
        }
    }
}

void System::PushMiddle()
{
    int n;
    for(n = 0; pStudent[n] != 0&&n < 30; n ++);
    Loop:
    pStudent[n] = new Middle_Student;
    pStudent[n]->Add();
    for(int i = 0; i < 30; i ++)
    {
//        这里必须先看i和n是否相等（不然我自己比我自己有什么意义？）
        if(i != n&&pStudent[i] != 0&&pStudent[i]->id == pStudent[n]->id)
        {
            cout<<"It seems that the ID had been recorded, please try again."<<endl<<endl;
            delete pStudent[n];
            goto Loop;
        }
    }
}

void System::PushCollege()
{
    int n;
    for(n = 0; pStudent[n] != 0&&n < 30; n ++);
    Loop:
    pStudent[n] = new College_Student;
    pStudent[n]->Add();
    for(int i = 0; i < 30; i ++)
    {
//        这里必须先看i和n是否相等（不然我自己比我自己有什么意义？）
        if(i != n&&pStudent[i] != 0&&pStudent[i]->id == pStudent[n]->id)
        {
            cout<<"It seems that the ID had been recorded, please try again."<<endl<<endl;
            delete pStudent[n];
            goto Loop;
        }
    }
}

//    通过ID查
int System::QueryById()
{
    string id;
    cout<<"please input the ID you have known: ";
    cin>>id;
    cout<<endl;
    int i;
    for(i = 0; i < 30; i ++)
    {
        if(pStudent[i] != 0&&id == pStudent[i]->id)
            break;
    }
    if(i < 30)
    {
        pStudent[i]->showInform();
        cout<<endl;
    //    在能够查询到的情况下进行编辑功能
        EditMenu:
        cout<<"Do you want to edit about it?(Y/N)"<<endl;
        cout<<"1.Yes"<<endl;
        cout<<"2.No"<<endl;
        int select;
        cout<<"your choice: ";
        cin>>select;
        cout<<endl;
        switch(select)
        {
        case 1:
            Edit(i);
            return 0;
            break;
        case 2:
            break;
        default:
            cout<<"Don't kid me!!!This is just two-way selection, does it seem difficult for you to make?"<<endl<<endl;
            goto EditMenu;
        }
        DeleteMenu:
        cout<<"Do you want to delete it?(Y/N)"<<endl;
        cout<<"1.Yes"<<endl;
        cout<<"2.No"<<endl;
        int judge;
        cout<<"your choice: ";
        cin>>judge;
        cout<<endl;
        switch(judge)
        {
        case 1:
            Delete(i);
            break;
        case 2:
            break;
        default:
            cout<<"Don't kid me!!!This is just two-way selection, does it seem difficult for you to make?"<<endl<<endl;
            goto DeleteMenu;
        }
    }
    else
        cout<<"We are sorry about failing to find the student, please check the ID."<<endl<<endl;
    return 0;
}

//    通过名字查
int System::QueryByName()
{
    string name;
    cout<<"please input the name you have known: ";
    cin>>name;
    cout<<endl;
    int i;
    for(i = 0; i < 30; i ++)
    {
        if(pStudent[i] != 0&&name == pStudent[i]->name)
            break;
    }
    if(i < 30)
    {
        pStudent[i]->showInform();
        cout<<endl;
    //    在能够查询到的情况下进行编辑功能
        EditMenu:
        cout<<"Do you want to edit about it?(Y/N)"<<endl;
        cout<<"1.Yes"<<endl;
        cout<<"2.No"<<endl;
        int select;
        cout<<"your choice: ";
        cin>>select;
        cout<<endl;
        switch(select)
        {
        case 1:
            Edit(i);
            break;
        case 2:
            break;
        case 3:
            cout<<"Don't kid me!!!This is just two-way selection, does it seem difficult for you to make?"<<endl<<endl;
            goto EditMenu;
        }
        DeleteMenu:
        cout<<"Do you want to delete it?(Y/N)"<<endl;
        cout<<"1.Yes"<<endl;
        cout<<"2.No"<<endl;
        int judge;
        cout<<"your choice: ";
        cin>>judge;
        cout<<endl;
        switch(judge)
        {
        case 1:
            Delete(i);
            break;
        case 2:
            break;
        default:
            cout<<"Don't kid me!!!This is just two-way selection, does it seem difficult for you to make?"<<endl<<endl;
            goto DeleteMenu;
        }
    }
    else
        cout<<"We are sorry about failing to find the student, please check the name."<<endl<<endl;
    return 0;
}

//    很简单的显示全部信息功能
void System::Display()
{
    for(int i = 0; i < 30; i ++)
    {
        if(pStudent[i] != 0)
            pStudent[i]->showInform();
    }
}

//    对于编辑功能，直接在原数据上进行数据覆盖显然是
//    不可行的（因为还要查ID是否重复），解决方法是
//    先new一个出来用来存储暂时的数据，之后再看是否覆盖。
void System::Edit(int n)
{
    Student* editor;
//    先要判断是哪种学生
    if(pStudent[n]->Type() == 1)
    {
        editor = new Middle_Student;
    }
    if(pStudent[n]->Type() == 2)
    {
        editor = new College_Student;
    }
    if(pStudent[n]->Type() == 0)
    {
        editor = new Pupil;
    }
    editor->Add();
    for(int i = 0; i < 30; i ++)
    {
//        在这里我一直犯了个错误，不能只查看id是否有重复，
//        还得先判断这里的i有没有数据，不然id没有可比性
//        （这里居然借鉴了JS编程思维）
        if(pStudent[i] != 0&&editor->id == pStudent[i]->id)
        {
            cout<<"It seems that the ID had been recorded, please try again next time."<<endl<<endl;
            delete editor;
            goto End;
        }
    }
    delete pStudent[n];
    pStudent[n] = editor;
    End:;
}

//  很简单的删除功能
void System::Delete(int n)
{
    delete pStudent[n];
    pStudent[n] = 0;
}

//    统计系统中所有学生总数
void System::TotalNum()
{
    int n = 0;
    for(int i = 0; i < 30; i ++)
    {
        if(pStudent[i] != 0)
            n ++;
    }
    cout<<"the total number of the students: "<<n<<endl<<endl;
}

//    统计系统中的男女人数
void System::StatGender()
{
    int boy = 0, girl = 0;
    for(int i = 0; i < 30; i ++)
    {
        if(pStudent[i] == 0)
            continue;
        else if(pStudent[i]->gender == 77)  //  “M”的ASC码是77
            boy ++;
        else if(pStudent[i]->gender == 70)  //  “F”的ASC码是70
            girl ++;
    }
    cout<<"the number of boys: "<<boy<<endl;
    cout<<"the number of girls: "<<girl<<endl<<endl;
}

//    统计系统中各个层级的学生人数
void System::StatLevel()
{
    int pupil = 0, middle = 0, college = 0;
    for(int i = 0; i < 30; i ++)
    {
        if(pStudent[i] == 0)
            continue;
        else if(pStudent[i]->Type() == 0)
            pupil ++;
        else if(pStudent[i]->Type() == 1)
            middle ++;
        else if(pStudent[i]->Type() == 2)
            college ++;
    }
    cout<<"the number of pupils: "<<pupil<<endl;
    cout<<"the number of middle school students: "<<middle<<endl;
    cout<<"the number of college school students: "<<college<<endl<<endl;
}

//    将文件里的数据写入到系统中
int System::FileIn()
{
    ifstream pupilin("pupil.txt",ios::binary);
    ifstream middlein("middle.txt",ios::binary);
    ifstream collegein("college.txt",ios::binary);
    if( (!pupilin) || (!middlein) || (!collegein) )
    {
        cout<<"We're sorry that the loading file process seems going wrong. There will be no information unless you add some."<<endl<<endl;
        return 0;
    }
    Pupil pupil_temp;
    Middle_Student middle_temp;
    College_Student college_temp;
    int i = 0;
    while(pupilin.peek() != EOF)
    {
        pupilin.read((char*)&pupil_temp, sizeof(Pupil));
        pStudent[i] = &pupil_temp;
        i ++;
    }
    while(middlein.peek() != EOF)
    {
        middlein.read((char*)&middle_temp, sizeof(Middle_Student));
        pStudent[i] = &middle_temp;
        i ++;
    }
    while(collegein.peek() != EOF)
    {
        collegein.read((char*)&college_temp, sizeof(College_Student));
        pStudent[i] = &college_temp;
        i ++;
    }
    pupilin.close();
    middlein.close();
    collegein.close();

    return 0;
}

//    将系统中的数据保存到文件中
int System::Save()
{
//    这里必须得先删除这几个文件，因为write函数默认不会覆盖写入，
//    而是接着写入，所以用到了remove函数
    remove("pupil.txt");
    remove("middle.txt");
    remove("college.txt");
    ofstream pupilout("pupil.txt",ios::binary);
    ofstream middleout("middle.txt",ios::binary);
    ofstream collegeout("college.txt",ios::binary);
    if( (!pupilout) || (!middleout) || (!collegeout) )
    {
        cout<<"Save failed!!!"<<endl<<endl;
        return 0;
    }
    for(int i = 0; i < 30; i ++)
    {
        if(pStudent[i] == 0)
            continue;
        else if(pStudent[i]->Type() == 0)
        {
            pupilout.write((char*)pStudent[i], sizeof(Pupil));
        }
        else if(pStudent[i]->Type() == 1)
        {
            middleout.write((char*)pStudent[i], sizeof(Middle_Student));
        }
        else if(pStudent[i]->Type() == 2)
        {
            collegeout.write((char*)pStudent[i], sizeof(College_Student));
        }
    }
    pupilout.close();
    middleout.close();
    collegeout.close();
    cout<<"All the information has been saved!"<<endl<<endl;

    return 0;
}


//    小学生的几个成员函数定义
void Pupil::Add()
{
    cout<<"the student's ID: ";
    cin>>id;
    cout<<"the student's name: ";
    cin>>name;
    cout<<"the gender(M/F): ";
    cin>>gender;
    cout<<"how old: ";
    cin>>age;
    cout<<"which class: ";
    cin>>classes;
    cout<<"English score: ";
    cin>>english_grade;
    cout<<"Math score: ";
    cin>>math_grade;
    cout<<"Chinese score: ";
    cin>>chinese_grade;
    cout<<"The information has been recorded!"<<endl<<endl;
}

void Pupil::showInform()
{
    cout<<"ID: "<<id<<"   "<<"name: "<<name<<"   ";
    cout<<"gender: "<<gender<<"   "<<"age: "<<age<<"   ";
    cout<<"Class: "<<classes<<"   ";
    cout<<"English score: "<<english_grade<<"   ";
    cout<<"Math score: "<<math_grade<<"   ";
    cout<<"Chinese score: "<<chinese_grade<<endl;
}


//    中学生的几个成员函数的定义
void Middle_Student::Add()
{
    cout<<"the student's ID: ";
    cin>>id;
    cout<<"the student's name: ";
    cin>>name;
    cout<<"the gender(M/F): ";
    cin>>gender;
    cout<<"how old: ";
    cin>>age;
    cout<<"which class: ";
    cin>>classes;
    cout<<"English score: ";
    cin>>english_grade;
    cout<<"Math score: ";
    cin>>math_grade;
    cout<<"Chinese score: ";
    cin>>chinese_grade;
    cout<<"Geography score: ";
    cin>>geog_grade;
    cout<<"History score: ";
    cin>>history_grade;
    cout<<"the student's address: ";
    cin>>address;
    cout<<"The information has been recorded!"<<endl<<endl;
}

void Middle_Student::showInform()
{
    cout<<"ID: "<<id<<"   "<<"name: "<<name<<"   ";
    cout<<"gender: "<<gender<<"   "<<"age: "<<age<<"   ";
    cout<<"Class: "<<classes<<"   ";
    cout<<"English score: "<<english_grade<<"   ";
    cout<<"Math score: "<<math_grade<<"   ";
    cout<<"Chinese score: "<<chinese_grade<<"   ";
    cout<<"Geography score: "<<geog_grade<<"   ";
    cout<<"History score: "<<history_grade<<"   ";
    cout<<"the address: "<<address<<endl;
}


//    几个大学生的成员函数定义
void College_Student::Add()
{
    cout<<"the student's ID: ";
    cin>>id;
    cout<<"the student's name: ";
    cin>>name;
    cout<<"the gender(M/F): ";
    cin>>gender;
    cout<<"how old: ";
    cin>>age;
    cout<<"which class: ";
    cin>>classes;
    cout<<"major in: ";
    cin>>major;
    cout<<"the student's address: ";
    cin>>address;
    cout<<"telephone: ";
    cin>>tel;
    cout<<"The information has been recorded!"<<endl<<endl;
}

void College_Student::showInform()
{
    cout<<"ID: "<<id<<"   "<<"name: "<<name<<"   ";
    cout<<"gender: "<<gender<<"   "<<"age: "<<age<<"   ";
    cout<<"Class: "<<classes<<"   ";
    cout<<"Major: "<<major<<"   ";
    cout<<"the address: "<<address<<"   ";
    cout<<"telephone: "<<tel<<endl;
}
